﻿using System.Drawing;
using System.Linq;

namespace NeuralLib
{
    public class KohonenMapLayer
    {
         protected int _inputsCount=0;

        public int InputsCount
        {
            get
            {
                return _inputsCount;
            }
        }

        public int NeuronsCount
        {
            get
            {
                return _neurons.Count();
            }
        }

        protected KohonenNeuron [] _neurons=null;
        public KohonenNeuron[] Neurons
        {
            get
            {
                return _neurons;
            }
        }

        protected int _neuronsXCount=0;
        public int NeuronsXCount
        {
            get
            {
                return _neuronsXCount;
            }
        }

        protected int _neuronsYCount = 0;
        public int NeuronsYCount
        {
            get
            {
                return _neuronsYCount;
            }
        }

        public int Winner(double [] inputs)
        {
            var neuronsCount = NeuronsXCount*NeuronsYCount;
            var winner = 0;
            var max = double.MinValue;

            for (var i = 0; i < neuronsCount; i++)
            {
                var measure = Neurons[i].Compute(inputs);
                if (!(measure > max)) continue;
                max = measure;
                winner = i;
            }
            return winner;
        }

        public KohonenMapLayer(int neuronsXCount, int neuronsYCount, int inputsCount, IKohonenMetricFunction function)
        {
            _inputsCount = inputsCount;
            _neuronsXCount = neuronsXCount;
            _neuronsYCount = neuronsYCount;
            var neuronsCount = neuronsXCount*neuronsYCount;
            _neurons = new KohonenNeuron[neuronsCount];

            for (var i = 0; i < neuronsXCount; i++)
                for (var j = 0; j < neuronsYCount; j++)
                    _neurons[i * NeuronsXCount + j] = new KohonenNeuron(inputsCount, new Point(i, j), function);           
        }    
    }
}
